//抽象工厂模式
#include<iostream>
#include<string>
#include<memory>
using namespace std;

class Fruit
{
public:
    Fruit(){}
    virtual void show()=0;
};
class Apple:public Fruit
{
public:
    void show() override
    {
        cout<<"这是一个苹果"<<endl;
    }
};
class Banana:public Fruit
{
public:
    void show() override
    {
        cout<<"这是一个香蕉"<<endl;
    }
};
class Animals
{
public:
    virtual void voice()=0;
};
class Dog:public Animals
{
public:
    void voice() override
    {
        cout<<"汪汪汪"<<endl;
    }
};
class Cat:public Animals
{
public:
    void voice() override
    {
        cout<<"喵喵喵"<<endl;
    }
};

class Factor
{
public:
    virtual shared_ptr<Fruit> getfruit(const string&)=0;
    virtual shared_ptr<Animals> getanimals(const string&)=0;
};
class FruitFactor:public Factor
{
public:
    shared_ptr<Animals> getanimals(const string& name) override
    {
        return nullptr;
    }
    shared_ptr<Fruit> getfruit(const string& name) override
    {
        if(name=="苹果"){
            return make_shared<Apple>();
        }
        else if(name=="香蕉"){
            return make_shared<Banana>();
        }
        return nullptr;
    }
};
class AnimalsFactor:public Factor
{
public:
    shared_ptr<Fruit> getfruit(const string& name) override
    {
        return nullptr;
    }
    shared_ptr<Animals> getanimals(const string& name) override
    {
        if(name=="小狗"){
            return make_shared<Dog>();
        }
        else if(name=="小猫"){
            return make_shared<Cat>();
        }
        return nullptr;
    }
};
class GetFactor
{
public:
    static shared_ptr<Factor> getfactor(const string& name)
    {
        if(name=="水果"){
            return make_shared<FruitFactor>();
        }
        else if(name=="动物"){
            return make_shared<AnimalsFactor>();
        }
        return nullptr;
    }
};
int main()
{
    shared_ptr<Factor> factor=GetFactor::getfactor("水果");
    shared_ptr<Fruit> fruit=factor->getfruit("苹果");
    fruit->show();
    fruit=factor->getfruit("香蕉");
    fruit->show();
    
    shared_ptr<Factor> factor1=GetFactor::getfactor("动物");
    shared_ptr<Animals> animals=factor1->getanimals("小狗");
    animals->voice();
    animals=factor1->getanimals("小猫");
    animals->voice();
    return 0;
}